// 参考链接
// https://developer.mozilla.org/zh-CN/docs/Web/API/Web_components/Using_custom_elements

const table_template = document.createElement("template");
table_template.innerHTML = `
    <style>
        :host{
            /* the shadow root */
            background-color: transparent; /* default */
            display: block; /* critical */
            width:600px;
            height:300px;
        }
        .table-container {
            display: block;
            width: 100%;
            margin: 20px auto;
            border: 1px solid #ddd;
            border-radius: 8px;
            overflow: hidden;
            height: 100%; /* 总容器高度 */
        }
        .table-header {
            background-color: #70fa31;
            padding: 5px 0;
            position: sticky;
            top: 0;
            z-index: 1;
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 2px;
            border-bottom: 2px solid #e61b1c;
            font-size: 25px;
            color: #ffffff;
            text-align: center;
        }
        .table-row {
            background-color: transparent;
            padding: 0px 0;
            top: 0;
            z-index: 1;
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 0px;
            border-bottom: 2px solid #0f19e6;
            text-align: center;
        }
        .table-body {
            height: calc(100% - 45px); /* 总高度减去表头高度 */
            overflow-y: hidden;
            display: grid;
            grid-template-columns: repeat(1, 1fr);
            gap: 2px;
            background-color: transparent;
            font-size: 20px;
            color: black;
        }
        /* 交替行颜色 */
        .table-body tr:nth-child(odd) {
            background-color: #dffaca;
        }

        .table-body tr:nth-child(even) {
            background-color: #f2dbff;
        }

        /* 悬停效果 */
        .table-body tr:hover {
            background-color: #e7f1ff;
            transition: all 0.3s ease;
        }

        .header-cell {
            padding: 8px 16px;
            font-weight: bold;
            text-align: left;
            box-sizing: border-box;
        }
        .row-cell {
            padding: 8px 16px;
            font-weight: bold;
            text-align: left;
            box-sizing: border-box;
            text-align: center;
        }
    </style>
    <div class="table-container">
        <div class="table-header">
        </div>
        <div class="table-body">
            <!-- 数据行将动态插入此处 -->
        </div>
    </div>
`;

class TableComponent extends HTMLElement {
    constructor() {
        super();
        this.attachShadow({ mode: "open" });
        let clone = table_template.content.cloneNode(true);
        this.shadowRoot.appendChild(clone);
        this.tableContainer = this.shadowRoot.querySelector('.table-container');
        this.tableHeader = this.shadowRoot.querySelector('.table-header');
        this.tableBody = this.shadowRoot.querySelector('.table-body');
        this.tabledata = {};
        this.autoScrollInterval = null;
        this.timerId = null;
    }
    get initscript() {
        return this.getAttribute("init-script");
    }
    set initscript(value) {
        // 可以进行数据过滤处理~
        this.setAttribute("init-script", value);
    }
    get timerscript() {
        return this.getAttribute("timer-script");
    }
    set timerscript(value) {
        // 可以进行数据过滤处理~
        this.setAttribute("timer-script", value);
    }
    get timer() {
        return this.getAttribute("timer");
    }
    set timer(value) {
        // 可以进行数据过滤处理~
        this.setAttribute("timer", value);
    }
    get dataurl() {
        return this.getAttribute("data-url");
    }
    set dataurl(value) {
        // 可以进行数据过滤处理~
        this.setAttribute("data-url", value);
    }


    initData(dataurl) {
        fetch(dataurl).then(response => {
            if (!response.ok) {
                throw new Error('Network response was not ok ' + response.statusText);
            }
            return response.json();
        }).then(data => {
            this.tabledata =  data;
            this.initHeader();
            this.initRows();
        }).catch(error => {
            console.error('There has been a problem with your fetch operation:', error);
        });
    }
    initHeader() {
        this.tableHeader.innerHTML = "";
        this.tabledata['headers'].forEach(header=>{
            const cell = document.createElement('div');
            cell.classname="header-cell";
            cell.innerHTML = header;
            this.tableHeader.appendChild(cell);
        });

    }
    initRows() {
        this.tableBody.innerHTML = "";
        this.tabledata['data'].forEach(rowData => {
            const row = document.createElement('tr');
            const table_row = document.createElement('div');
            table_row.setAttribute('class','table-row');
            Object.entries(rowData).forEach(([key, value]) => {
                if (key !== 'style') {
                const cell_div = document.createElement('div');
                cell_div.setAttribute('class','row-cell');
                const span = document.createElement('span');
                span.innerHTML = value;
                cell_div.appendChild(span);
                table_row.appendChild(cell_div);
            }
            });

            // Apply custom styles if provided
            if (rowData.style) {
                table_row.style.backgroundColor = rowData.style.backginnerHtmroundColor || '';
            }

            row.appendChild(table_row);
            this.tableBody.appendChild(row);
        });
    }
    // 启动/停止自动滚动
    toggleAutoScroll(speed) {
        if (this.autoScrollInterval) {
            clearInterval(this.autoScrollInterval);
            this.autoScrollInterval = null;
            this.autoScrollInterval = setInterval( ()=> {
                if (this.tableBody.scrollTop >= this.tableBody.scrollHeight - this.tableBody.clientHeight -2) {
                    this.tableBody.scrollTop = 0;
                } else {
                    this.tableBody.scrollTop += 1;
                }
            }, speed);
        } else {
            this.autoScrollInterval = setInterval( ()=> {
                if (this.tableBody.scrollTop >= this.tableBody.scrollHeight - this.tableBody.clientHeight -2) {
                    this.tableBody.scrollTop = 0;
                } else {
                    this.tableBody.scrollTop += 1;
                }
            }, speed);
        }
    }

    updateData(dataurl) {
        fetch(dataurl).then(response => {
            if (!response.ok) {
                throw new Error('Network response was not ok ' + response.statusText);
            }
            return response.json();
        }).then(data => {
            this.tabledata =  data;
            this.initHeader();
            this.initRows();
        }).catch(error => {
            console.error('There has been a problem with your fetch operation:', error);
        });
    }
    disconnectedCallback() {
        // 清除定时器以避免内存泄漏
        clearInterval(this.timerId);
    }
    // 定时器
    setTimer(interval) {
        // 清除之前的定时器
        clearInterval(this.timerId);
        // 创建新的定时器
        if (interval > 0){
            // 设置新的定时器
            this.timerId = setInterval(() => {
                    this.executeScript();
            }, interval);
        }

    }
    executeScript(){
        if (this.timerscript != ""){
            try {
                eval(this.timerscript);
            } catch (error) {
                console.log(error.message);
            }
        }
        else{
            console.log("no script to execute");
        }

    }
    connectedCallback() {
        const data_url = this.getAttribute('data-url') || '';
        const scroll_speed = this.getAttribute('scroll-speed') || 0;
        const bg_color = this.getAttribute('bg-color') || 0;
        const init_script = this.getAttribute('init-script');
        if (data_url != ""){
            this.initData(data_url);
        }
        if (init_script != ""){
            try {
                eval(init_script);
            } catch (error) {
                console.log(error.message);
            }
        }

        if (scroll_speed>0){
            this.toggleAutoScroll(scroll_speed);
        }
        this.tableContainer.style.backgroundColor = bg_color;
        const head_bg_color = this.getAttribute('head-bg-color') || "";
        this.tableHeader.style.backgroundColor = head_bg_color;
        const head_font_color = this.getAttribute('head-font-color') || "";
        this.tableHeader.style.color = head_font_color;
        const head_font_size = this.getAttribute('head-font-size') || "25px";
        this.tableHeader.style.fontSize = head_font_size;

        const body_font_color = this.getAttribute('body-font-color') || "";
        this.tableBody.style.color = body_font_color;
        const body_font_size = this.getAttribute('body-font-size') || "20px";
        this.tableBody.style.fontSize = body_font_size;

        const body_odd_color = this.getAttribute('body-odd-color') || "";
        const oddRows = this.tableBody.querySelectorAll('.table-body tr:nth-child(odd)');
        oddRows.forEach(row => {
            row.style.backgroundColor = body_odd_color; // Change background color to gold
        });

        const body_even_color = this.getAttribute('body-even-color') || "";
        const evenRows = this.tableBody.querySelectorAll('.table-body tr:nth-child(even)');
        evenRows.forEach(row => {
            row.style.backgroundColor = body_even_color; // Change background color to gold
        });

        const timer = this.getAttribute('timer');
        const timer_script = this.getAttribute('timer-script');
        if (parseInt(timer) > 0 && timer_script !="")
        {
            this.setTimer(parseInt(timer)*1000);
        }

    }
    static get observedAttributes() {
        return ['data-url','scroll-speed','bg-color','head-font-size','head-font-color',
            'body-font-size','head-bg-color','body-font-color','row-odd-color','row-even-color',
            'init-script','timer','timer-script'];
    }
    attributeChangedCallback(name, oldValue, newValue) {
        if (name.toLowerCase() === "data-url") {
            this.updateData(newValue);
        }
        else if (name.toLowerCase() === "scroll-speed") {
            this.toggleAutoScroll(newValue);
        }
        else if (name.toLowerCase() === "bg-color") {
            this.tableContainer.style.backgroundColor = newValue;
        }
        else if (name.toLowerCase() === "head-font-size") {
            this.tableHeader.style.fontSize = newValue;
        }else if (name.toLowerCase() === "head-font-color") {
            this.tableHeader.style.color = newValue;
        }
        else if (name.toLowerCase() === "head-bg-color") {
            this.tableHeader.style.backgroundColor = newValue;
        }
        else if (name.toLowerCase() === "body-font-size") {
            this.tableBody.style.fontSize = newValue;
        }else if (name.toLowerCase() === "body-font-color") {
            this.tableBody.style.color = newValue;
        }else if (name.toLowerCase() === "row-odd-color") {
            const oddRows = this.tableBody.querySelectorAll('.table-body tr:nth-child(odd)');
            oddRows.forEach(row => {
                row.style.backgroundColor = newValue; // Change background color to gold
            });
        }else if (name.toLowerCase() === "row-even-color") {
            const evenRows = this.tableBody.querySelectorAll('.table-body tr:nth-child(even)');
            evenRows.forEach(row => {
                row.style.backgroundColor = newValue; // Change background color to gold
            });
        }else if (name.toLowerCase() === "timer-script") {
            if (this.timerscript == ""){
                clearInterval(this.timerId)
            }
            else{
                this.setTimer(parseInt(this.timer)*1000);
            }
        }else if (name.toLowerCase() === "timer") {
            if (parseInt(newValue) > 0) {
                this.setTimer(parseInt(newValue)*1000);
            }
            else{
                clearInterval(this.timerId);
            }
        }
    }
}

customElements.define("table-component", TableComponent);

